package org.diysearch.dao.impls;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.diysearch.dao.interfaces.UserDao;
import org.diysearch.helpers.UserHelper;
import org.diysearch.models.User;
import org.diysearch.models.UserElement;
import org.diysearch.models.UserIp;
import org.diysearch.tools.StringTools;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class UserDaoImpl extends SqlMapClientDaoSupport implements UserDao {
	private static final Log LOG = LogFactory.getLog(UserDaoImpl.class);
	
	public User authenticate(User u) throws SQLException {
		User _u = (User) getSqlMapClientTemplate().queryForObject("authenticate-user",u);
		if (_u == null) {
			return null;
		} else {
			// lets log their ip address
			try {
				UserHelper.logIp(u);
			} catch (Exception ex) {
				LOG.warn("could not log user ip: ");
				LOG.warn(StringTools.getStackTrace(ex));
			}
			return _u;
		}
	}

	@Override
	public void insertUserIp(User u) throws SQLException {
		for (UserIp uip : u.getIpAddrs()) {
			UserIp ip = (UserIp) getSqlMapClientTemplate().queryForObject("findUserIpByIpAndUid",uip);
			if (ip == null) {
				getSqlMapClientTemplate().insert("insert-user-ip",uip);
			}
		}
	}

	public int delete(User u) throws SQLException {
		int code = 0;
		code += getSqlMapClientTemplate().delete("delete-user",u);
		code += getSqlMapClientTemplate().delete("delete-user-element",u);
		code += getSqlMapClientTemplate().delete("delete-user-ip",u);
		return code;
	}

	public List<User> findActive() throws SQLException {
		return (List<User>) getSqlMapClientTemplate().queryForList("findActive-users");
	}

	public User findByEmail(String email) throws SQLException {
		User u = new User();
		u.setEmail(email);
		return (User) getSqlMapClientTemplate().queryForObject("findByEmail-user",u);
	}

	public User findById(int id) throws SQLException {
		User u = new User();
		u.setId(id);
		return (User) getSqlMapClientTemplate().queryForObject("findById-user",u);
	}

	public int save(User u) throws SQLException {
		int code = 0;
		if (u.getId() == 0) {
			// new user, insert
			int uid = ((User) getSqlMapClientTemplate().insert("insert-user",u)).getId();
			if (u.getElements() != null) {
				for (UserElement ue : u.getElements()) {
					ue.setUid(uid);
					UserElement _ue = (UserElement) getSqlMapClientTemplate().insert("insert-user-element",ue);
				}
			}
			code = uid;
			return code;
		} else {
			// existing user, update
			code = getSqlMapClientTemplate().update("update-user",u);
			if (u.getElements() != null) {
				for (UserElement ue : u.getElements()) {
					code+= getSqlMapClientTemplate().update("update-user-element",ue);
				}
			}
			return code;
		}
	}

	public User findByUsername(String username) throws SQLException {
		User _u = (User) getSqlMapClientTemplate().queryForObject("findByUsername",username);
		if (_u == null) {
			return null;
		} else {
			return _u;
		}
	}

	@Override
	public int incrementRating(User u) throws SQLException {
		return getSqlMapClientTemplate().update("increment-user-rating",u);
	}

	@Override
	public User findByToken(User u) throws SQLException {
		return (User) getSqlMapClientTemplate().queryForObject("findByToken",u);
	}
	
}
